import { addDays } from 'date-fns';
import { BadRequestException, Injectable } from '@nestjs/common';
import { PrismaService } from '../../libs/prisma/prisma.service';
import { UserRoleType } from '@prisma/client';
import { GetListDto } from './dto/get-list.dto';
import { CreateDto } from './dto/create.dto';
import { randomUUID } from 'crypto';

@Injectable()
export class CardService {
  constructor(private readonly prisma: PrismaService) {}

  async useKey(key: string, userId: string) {
    const card = await this.prisma.cardKey.findUnique({ where: { key } });
    // 1 判断卡密是否存在
    if (!card) throw new BadRequestException('卡密不存在');
    // 2 判断卡密是否已被使用
    if (card.isUsed) throw new BadRequestException('卡密已被使用');
    // 3 判断用户是否存在
    const user = await this.prisma.user.findUnique({ where: { id: userId } });
    if (!user) throw new BadRequestException('用户不存在');
    // 4 使用卡密
    await this.prisma.cardKey.update({
      where: { key },
      data: {
        isUsed: true,
        useTime: new Date(),
        usedById: userId,
      },
    });
    // 5 查询卡密对应角色和积分
    const roleItem = await this.prisma.userRole.findUnique({ where: { id: card.usedRoleId } });
    if (!roleItem) throw new BadRequestException('卡密对应角色不存在');
    // 5.1 用户角色和卡密角色一致，时间叠加
    if (user.roleId === card.usedRoleId) {
      const updateUser = await this.prisma.user.update({
        where: { id: userId },
        data: {
          vipStartTime: user.vipStartTime ? new Date(Math.min(user.vipStartTime.getTime(), Date.now())) : new Date(),
          vipEndTime: user.vipEndTime ? addDays(user.vipEndTime, card.duration) : addDays(new Date(), card.duration),
          userRole: {
            connect: { id: card.usedRoleId },
          },
        },
        select: {
          vipStartTime: true,
          vipEndTime: true,
        },
      });
      return { ...updateUser, role: roleItem.role };
    }
    // 5.2 不一致，直接更新用户角色
    else {
      const updateUser = await this.prisma.user.update({
        where: { id: userId },
        data: {
          vipStartTime: new Date(),
          vipEndTime: addDays(new Date(), card.duration),
          userRole: {
            connect: { id: card.usedRoleId },
          },
        },
        select: {
          vipStartTime: true,
          vipEndTime: true,
        },
      });
      return { ...updateUser, role: roleItem.role };
    }
  }

  async check(key: string, userId: string) {
    // 1 判断卡密是否存在
    const card = await this.prisma.cardKey.findUnique({ where: { key } });
    if (!card) throw new BadRequestException('卡密不存在');
    // 2 判断卡密是否已被使用
    if (card.isUsed) throw new BadRequestException('卡密已被使用');
    // 3 判断用户角色和卡密角色是否一致
    const user = await this.prisma.user.findUnique({ where: { id: userId } });
    if (!user) throw new BadRequestException('用户不存在');
    const userRole = await this.prisma.userRole.findUnique({ where: { id: user.roleId } });
    if (!userRole) throw new BadRequestException('用户角色不存在');
    // 4 用户为默认角色，直接返回
    if (userRole.role === UserRoleType.NORMAL) return true;
    // 5 判断用户角色和卡密角色一致
    return userRole.id === card.usedRoleId;
  }

  async getList(getListDto: GetListDto) {
    // 1 校验键值
    if (getListDto.roleKey !== 'admin') throw new BadRequestException('非法操作');
    // 2 查询角色
    const role = await this.prisma.userRole.findUnique({ where: { role: getListDto.roleType } });
    if (!role) throw new BadRequestException('角色不存在');
    // 3 查询卡密
    const cards = await this.prisma.cardKey.findMany({
      where: { usedRoleId: role.id, isUsed: getListDto.isUsed, duration: +getListDto.duration || 30 },
      skip: (getListDto.page - 1) * getListDto.pageSize,
      take: getListDto.pageSize,
    });
    // 4 铺平数组
    if (getListDto.flat) {
      return {
        list: cards.map((item) => item.key).join('\n'),
        total: cards.length,
      };
    }
    // 5 正常返回
    return {
      list: cards,
      total: cards.length,
    };
  }

  async create(userId: string, createDto: CreateDto) {
    // 1 查询用户
    const user = await this.prisma.user.findUnique({ where: { id: userId } });
    if (!user) throw new BadRequestException('用户不存在');
    // 2 判断邮箱
    if (user.email !== '15360001247@163.com') throw new BadRequestException('非法操作');
    // 3 查询角色
    const role = await this.prisma.userRole.findUnique({ where: { role: createDto.roleType } });
    if (!role) throw new BadRequestException('角色不存在');
    // 4 创建卡密
    const data = Array.from({ length: createDto.number }).map(() => ({
      key: randomUUID(),
      usedRoleId: role.id,
      duration: createDto.duration,
    }));
    await this.prisma.cardKey.createMany({ data });
    return data;
  }
}
